package com.arvato.admin01.controller;

import com.arvato.admin01.Util.AopLogger;
import com.arvato.admin01.pojo.DataResult;
import com.arvato.admin01.pojo.ExportYqfkdj;
import com.arvato.admin01.pojo.Student;
import com.arvato.admin01.service.StudentService;
import com.arvato.admin01.service.impl.StudentServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author xu yuanjun
 * @data 2020/3/29 15:36
 * 上面的代码，是一个典型的写法：当查询的时候，先从Redis集群中取，如果没有，那么再从DB中查询并设置到Redis集群中。
注意，在实际开发中，我们一般在缓存中，存储的数据结构是JSON。（JDK提供的序列化方式效率稍微比JSON序列化低一些；而且JDK序列化非常严格，字段的增减，就很可能导致反序列失败，而JSON这方面兼容性较好）
假设从DB中查询需要2S，那么显然这段时间内过来的请求，在上述的代码下，会全部走DB查询，相当于缓存被直接穿透，这样的现象就称之为“缓存击穿”！
上面代码，在缓存有数据时，让查询缓存的请求不必排队，减小了同步的粒度。但是，仍然没有解决缓存击穿的问题。
虽然，多个查询DB的请求进行排队，但是即便一个DB查询请求完成并设置到缓存中，其他查询DB的请求依然会继续查询DB！
 */
@RestController
@RequestMapping("/cache")
public class CacheController {

    @Autowired
    private StudentService studentService;

    /**
      * @author XUYU005
      * @description
      * @date 17:00 2020/4/2
      * @param [] 查询 使用 缓存
      * @return java.util.List<com.arvato.admin01.pojo.Student>
      */
    @RequestMapping("/getUsers")
    @AopLogger(describe = "添加用户")
    public List<Student> getCache(){
        return studentService.query();

    }

    /**
      * @author XUYU005
      * @description
      * @date 17:00 2020/4/2
      * @param [] 查询  防止 缓存穿透 缓存数组
      * @return java.util.List<com.arvato.admin01.pojo.Student>
      */
    @RequestMapping("/queryNew")
    public List<Student> getCachenew(){
        return studentService.queryNew();

    }

    /**
     * @author XUYU005
     * @description
     * @date 17:00 2020/4/2
     * @param [] 查询  防止 缓存穿透 缓存对象
     * @return java.util.List<com.arvato.admin01.pojo.Student>
     */
    @RequestMapping("/queryObject")
    public Student getCachenewObject(){
        return studentService.queryObject();
    }

    /**
     * @author XUYU005
     * @description
     * @date 17:00 2020/4/2
     * @param [] 查询  防止 缓存穿透 缓存 字符串
     * @return java.util.List<com.arvato.admin01.pojo.Student>
     */
    @RequestMapping("/getUsersnewString")
    public String getCachenewString(){
        return studentService.queryString();
    }


    @RequestMapping("/insertData")
    public void insertData( @RequestParam String name, @RequestParam String email) throws Exception {
        studentService.insertData(name,email);
    }

    @RequestMapping(value = "/getExcel", method = RequestMethod.POST)
    public void exportKhfxxx(@RequestBody ExportYqfkdj yqfkdjBean, HttpServletResponse resp) throws Exception {
        DataResult result = new DataResult();
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyyMMddhhmmssSSS");
            result = studentService.exporYqfkdj(yqfkdjBean);
            String filepath = result.getMsg().replace("\"", "");
            File file = new File(filepath);
            String filename = "疫情防控信息" + df.format(new Date()) + ".xlsx";
            InputStream fis = new BufferedInputStream(new FileInputStream(filepath));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            resp.reset();
            resp.setHeader("Content-Disposition",
                    "attachment;filename=" + new String(filename.replaceAll(" ", "").getBytes("gbk")));
            resp.setHeader("Content-Length", "" + file.length());
            OutputStream os = new BufferedOutputStream(resp.getOutputStream());
            resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            // 输出文件
            os.write(buffer);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            //log.info(YqfkdjUtils.Cytx.DCSB);
            throw e;
        }
    }
}
